﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace UtilZ.Dotnet.WindowsDesktopEx.WPF
{
    /// <summary>
    /// EllipseRotateLoadingControl.xaml 的交互逻辑
    /// </summary>
    public partial class EllipseRotateLoadingControl : UserControl
    {
        /// <summary>
        /// 置旋转圆直径依赖属性
        /// </summary>
        public static readonly DependencyProperty EllipseSizeProperty =
            DependencyProperty.RegisterAttached(nameof(EllipseSize),
                typeof(double),
                typeof(EllipseRotateLoadingControl),
                new PropertyMetadata(3.0d, PropertyChanged));

        /// <summary>
        /// 旋转方向依赖属性
        /// </summary>
        public static readonly DependencyProperty RotateDirectionProperty =
            DependencyProperty.RegisterAttached(nameof(RotateDirection),
                typeof(bool),
                typeof(EllipseRotateLoadingControl),
                new PropertyMetadata(true, PropertyChanged));

        /// <summary>
        /// 转一圈的时长依赖属性
        /// </summary>
        public static readonly DependencyProperty DurationMillisecondsProperty =
            DependencyProperty.RegisterAttached(nameof(DurationMilliseconds),
                typeof(double),
                typeof(EllipseRotateLoadingControl),
                new PropertyMetadata(1200d, PropertyChanged));

        /// <summary>
        /// 旋转圆填充笔刷依赖属性
        /// </summary>
        public static readonly DependencyProperty FillBrushesProperty =
            DependencyProperty.RegisterAttached(nameof(FillBrushes),
                typeof(Brush[]),
                typeof(EllipseRotateLoadingControl),
                new PropertyMetadata(GetDefaultFillBrushes(), PropertyChanged));
        private static Brush[] GetDefaultFillBrushes()
        {
            return new Brush[]
            {
                Brushes.Gray,
                Brushes.Gray,
                Brushes.Gray,
                Brushes.Gray,
                Brushes.Gray,
                Brushes.Gray,
                Brushes.Gray,
                Brushes.Gray,
            };
        }



        /// <summary>
        /// 获取或设置旋转圆直径
        /// </summary>
        public double EllipseSize
        {
            get
            {
                return (double)this.GetValue(EllipseSizeProperty);
            }
            set
            {
                if (value < 1)
                {
                    throw new ArgumentOutOfRangeException($"最大尺寸值不能小于最小尺寸值1,值{value}无效");
                }

                if (value > 1000)
                {
                    throw new ArgumentOutOfRangeException($"最大尺寸值不能大于1000,值{value}无效");
                }

                this.SetValue(EllipseSizeProperty, value);
            }
        }


        /// <summary>
        /// 获取或设置旋转方向[true:顺时针;false:逆时针]
        /// </summary>
        public bool RotateDirection
        {
            get
            {
                return (bool)this.GetValue(RotateDirectionProperty);
            }
            set
            {
                this.SetValue(RotateDirectionProperty, value);
            }
        }



        /// <summary>
        /// 获取或设置转一圈的时长,单位毫秒
        /// </summary>
        public double DurationMilliseconds
        {
            get
            {
                return (double)this.GetValue(DurationMillisecondsProperty);
            }
            set
            {
                this.SetValue(DurationMillisecondsProperty, value);
            }
        }


        /// <summary>
        /// 获取或设置旋转圆填充笔刷
        /// </summary>
        public Brush[] FillBrushes
        {
            get
            {
                return (Brush[])this.GetValue(FillBrushesProperty);
            }
            set
            {
                this.SetValue(FillBrushesProperty, value);
            }
        }



        /// <summary>
        /// 旋转动画
        /// </summary>
        private Storyboard _storyboard = null;

        /// <summary>
        /// 
        /// </summary>
        public EllipseRotateLoadingControl()
        {
            InitializeComponent();

            this.CreateStoryboard();

            this.UpdateEllipseSize(this.EllipseSize);
            //this.UpdateRotateDirection(this.RotateDirection);
            //this.UpdateDurationMilliseconds(this.DurationMilliseconds);
            this.UpdateFillBrushes(this.FillBrushes);
        }

        private void CreateStoryboard()
        {
            if (this._storyboard != null)
            {
                this._storyboard.Stop();
            }

            DoubleAnimation doubleAnimation = new DoubleAnimation();
            doubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
            doubleAnimation.AutoReverse = false;
            doubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(this.DurationMilliseconds));
            if (this.RotateDirection)
            {
                doubleAnimation.From = 0d;
                doubleAnimation.To = 360d;
            }
            else
            {
                doubleAnimation.From = 360d;
                doubleAnimation.To = 0d;
            }

            Storyboard storyboard = new Storyboard();
            storyboard.Children.Add(doubleAnimation);
            Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(RenderTransform).(TransformGroup.Children)[0].(Angle)"));
            grid.BeginStoryboard(storyboard, HandoffBehavior.Compose, true);
            this._storyboard = storyboard;
        }



        /// <summary>
        /// 依赖属性值改变事件
        /// </summary>
        /// <param name="d">依赖父控件</param>
        /// <param name="e">属性参数</param>
        private static void PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var self = d as EllipseRotateLoadingControl;
            if (e.Property == EllipseSizeProperty)
            {
                self.UpdateEllipseSize((double)e.NewValue);
            }
            else if (e.Property == RotateDirectionProperty)
            {
                self.UpdateRotateDirection((bool)e.NewValue);
            }
            else if (e.Property == DurationMillisecondsProperty)
            {
                self.UpdateDurationMilliseconds((double)e.NewValue);
            }
            else if (e.Property == FillBrushesProperty)
            {
                self.UpdateFillBrushes((Brush[])e.NewValue);
            }
            else
            {

            }
        }

        private void UpdateFillBrushes(Brush[] fillBrushes)
        {
            int brushIndex = 0;

            Brush brush;
            foreach (var ele in grid.Children)
            {
                Ellipse ellipse = ele as Ellipse;
                if (ellipse == null)
                {
                    continue;
                }

                brush = fillBrushes[brushIndex];
                brushIndex++;
                if (brushIndex > fillBrushes.Length)
                {
                    brushIndex = 0;
                }

                ellipse.Fill = brush;
            }
        }



        private void UpdateDurationMilliseconds(double durationMilliseconds)
        {
            //BeginStoryboard beginStoryboard = (BeginStoryboard)(((EventTrigger)grid.Style.Triggers.First()).Actions.First());
            //DoubleAnimation oldDoubleAnimation = (DoubleAnimation)beginStoryboard.Storyboard.Children.First();

            //DoubleAnimation newDoubleAnimation = new DoubleAnimation(oldDoubleAnimation.From.Value,
            //    oldDoubleAnimation.To.Value,
            //    new Duration(TimeSpan.FromMilliseconds(durationMilliseconds)));

            //Storyboard storyboard = new Storyboard();
            //storyboard.Children.Add(newDoubleAnimation);
            //beginStoryboard.Storyboard = storyboard;

            this.CreateStoryboard();
        }

        private void UpdateRotateDirection(bool rotateDirection)
        {
            //BeginStoryboard beginStoryboard = (BeginStoryboard)(((EventTrigger)grid.Style.Triggers.First()).Actions.First());
            //DoubleAnimation oldDoubleAnimation = (DoubleAnimation)beginStoryboard.Storyboard.Children.First();

            //DoubleAnimation newDoubleAnimation = new DoubleAnimation();
            //newDoubleAnimation.Duration = oldDoubleAnimation.Duration;

            //if (rotateDirection)
            //{
            //    newDoubleAnimation.From = 0d;
            //    newDoubleAnimation.To = 360d;
            //}
            //else
            //{
            //    newDoubleAnimation.From = 360d;
            //    newDoubleAnimation.To = 0d;
            //}

            //Storyboard storyboard = new Storyboard();
            //storyboard.Children.Add(newDoubleAnimation);
            //beginStoryboard.Storyboard = storyboard;

            this.CreateStoryboard();
        }

        private void UpdateEllipseSize(double ellipseSize)
        {
            foreach (var ele in grid.Children)
            {
                Ellipse ellipse = ele as Ellipse;
                if (ellipse == null)
                {
                    continue;
                }

                ellipse.Width = ellipseSize;
                ellipse.Height = ellipseSize;
            }
        }
    }
}
